<?php
/**
 * File Name...: helpers\helpers.php
 * Framework...: Blackbird Framework
 * Author......: KnKill, 2010 (c) KnKill Corporation
 */



/**
 * @package Blackbird Framework
 * @subpackage Helpers
 * @since 0.2
 */
class TextHelpers
{


/**
 * @static
 * @access public
 * @since 0.2
 * @param string $string
 * @param integer $limit
 * @param string $endChar
 * @return string
 */
static public function word_limiter($string, $limit = 100, $end_char = '&#8230;') {
    if (trim($string) == '') {
        return $string;
    }
    
    $regExp = '/^\s*+(?:\S++\s*+){1,'. intval($limit) . '}/';
    preg_match($regExp, $string, $matches);
    
    // Если количество слов меньше лимита, символы в конце строки не нужны
    if (strlen($string) == strlen($matches[0])) {
        $endChar = '';
    }
    
    return rtrim($matches[0]) . $end_char;
}


/**
 * @static
 * @access public
 * @since 0.2
 * @param string $string
 * @param integer $limit
 * @param string $endChar
 * @return string
 */
static public function character_limiter($string, $limit = 500, $end_char = '&#8230;') {
    // Если в строке символов меньше, чем указано параметром limit - возвращаем
    // исходную строку
    if (strlen($string) < $limit) {
        return $string;
    }
    $string = preg_replace("/\s+/", ' ', str_replace(array("\r\n", "\r", "\n"), ' ', $string));
    if (strlen($string) <= $limit) {
        return $string;
    }
    $out = '';
    foreach (explode(' ', trim($string)) as $value) {
        $out .= $value . ' ';
        if (strlen($out) >= $limit) {
            $out = trim($out);
            return (strlen($out) == strlen($string)) ? $out : $out . $end_char;
        }
    }
}


/**
 * @static
 * @access public
 * @since 0.2
 * @param string $string
 * @return string
*/
static public function ascii_to_entities($string) {
    // Инициализирование необохдимых переменных
    $count = 1;
    $out   = '';
    $temp  = array();
    
    for ($i = 0, $s = strlen($string); $i < $s; $i++) {
        $ordinal = ord($string[$i]);
        if ($ordinal < 128) {
            if (count($temp) == 1) {
                $out  .= '&#' . array_shift($temp) . ';';
                $count = 1;
            }
            $out .= $string[$i];
        } else {
            if (count($temp) == 0) {
                $count = ($ordinal < 224) ? 2 : 3;
            }
            $temp[] = $ordinal;
            if (count($temp) == $count) {
                $tmp1 = (($temp['0'] % 16) * 4096) + (($temp['1'] % 64) * 64) + ($temp['2'] % 64);
                $tmp2 = (($temp['0'] % 32) * 64) + ($temp['1'] % 64);
                $number = ($count == 3) ? $tmp1 : $tmp2;
                $out .= '&#'.$number . ';';
                $count = 1;
                $temp = array();
            }
        }
    }
    return $out;
}


/**
 * @static
 * @access public
 * @since 0.2
 * @param string $string
 * @param bool $all
 * @return string
*/
static public function entities_to_ascii($string, $all = true) {
    if (preg_match_all('/\&#(\d+)\;/', $string, $matches)) {
        for ($i = 0, $s = count($matches['0']); $i < $s; $i++) {
            $digits = $matches['1'][$i];
            $out = '';
            if ($digits < 128) {
                $out .= chr($digits);
            } elseif ($digits < 2048) {
                $out .= chr(192 + (($digits - ($digits % 64)) / 64));
                $out .= chr(128 + ($digits % 64));
            } else {
                $out .= chr(224 + (($digits - ($digits % 4096)) / 4096));
                $out .= chr(128 + ((($digits % 4096) - ($digits % 64)) / 64));
                $out .= chr(128 + ($digits % 64));
            }
            $string = str_replace($matches['0'][$i], $out, $string);
        }
    }
    
    // Преобразование спец-символов
    if ($all) {
        $entities = array("&amp;", "&lt;", "&gt;", "&quot;", "&apos;", "&#45;");
        $chars    = array("&", "<", ">", "\"", "'", "-");
        $string   = str_replace($entities, $chars, $string);
    }
    return $string;
}


/**
 * @static
 * @access public
 * @since 0.2
 * @param string $string
 * @param array $censored
 * @param string $replament
 * @return string
 */
static public function word_censor($string, $censored, $replacement = '') {
    if ( !is_array($censored)) {
     return $string;
    }
    
    $string = ' ' . $string . ' ';
    $delim  = '[-_\'\"`(){}<>\[\]|!?@#%&,.:;^~*+=\/ 0-9\n\r\t]';
    
    foreach ($censored as $bad_word) {
        if ($replacement != '') {
            $string = preg_replace("/({$delim})(".str_replace('\*', '\w*?', preg_quote($bad_word, '/')).")({$delim})/i", "\\1{$replacement}\\3", $string);
        } else {
            $string = preg_replace("/({$delim})(".str_replace('\*', '\w*?', preg_quote($bad_word, '/')).")({$delim})/ie", "'\\1'.str_repeat('#', strlen('\\2')).'\\3'", $string);
        }
    }
    return trim($string);
}


/**
 * @static
 * @access public
 * @since 0.2
 * @param string $string
 * @return string
 */
static public function highlight_code($string) {
    $string = str_replace(array('&lt;', '&gt;'), array('<', '>'), $string);
    $tags1 = array('<?', '?>', '<%', '%>', '\\', '</script>');
    $tags2 = array('phptagopen', 'phptagclose', 'asptagopen', 'asptagclose', 'backslashtmp', 'scriptclose');
    $string = str_replace($tags1, $tags2, $string);
    $string = '<?php ' . $string . ' ?>';
    $string = highlight_string($string, true);
    
    if (abs(PHP_VERSION) < 5) {
        $string = str_replace(array('<font ', '</font>'), array('<span ', '</span>'), $string);
        $string = preg_replace('#color="(.*?)"#', 'style="color: \\1"', $string);
    }
    
    $string = preg_replace('/<span style="color: #([A-Z0-9]+)">&lt;\?php(&nbsp;| )/i', '<span style="color: #$1">', $string);
    $string = preg_replace('/(<span style="color: #[A-Z0-9]+">.*?)\?&gt;<\/span>\n<\/span>\n<\/code>/is', "$1</span>\n</span>\n</code>", $string);
    $string = preg_replace('/<span style="color: #[A-Z0-9]+"\><\/span>/i', '', $string);
    
    $tags1 = array('phptagopen', 'phptagclose', 'asptagopen', 'asptagclose', 'backslashtmp', 'scriptclose');
    $tags2 = array('&lt;?', '?&gt;', '&lt;%', '%&gt;', '\\', '&lt;/script&gt;');
    $string = str_replace($tags1, $tags2, $string);
    
    return $string;
}


/**
 * @static
 * @access public
 * @since 0.2
 * @param string $string
 * @param string $phrase
 * @param string $pre
 * @param string $post
 * @return string
 */
static public function highlight_phrase($string, $phrase, $pre = '<b>', $post = '</b>') {
    if ($string == '') {
        return '';
    }
    if ($phrase != '') {
        return preg_replace('/(' . preg_quote($phrase, '/') . ')/i', $pre . "\\1" . $post, $string);
    }
    return $string;
}


/**
 * @static
 * @access public
 * @since 0.2
 * @param string $string
 * @param integer $charLimit
 * @return string
 */
static public function word_wrap($string, $char_limit = 76) {
    // Если переменная $charLimit имеет нечисловоее значение, воспользуемся значением
    // по умолчанию: 76
    if ( !is_numeric($char_limit)) {
        $char_limit = 76;
    }
    
    $string = preg_replace("| +|", " ", $string);
    
    if (strpos($string, "\r") !== false) {
        $string = str_replace(array("\r\n", "\r"), "\n", $string);
    }
    
    $unwrap = array();
    if (preg_match_all("|(\{unwrap\}.+?\{/unwrap\})|s", $string, $matches)) {
        for ($i = 0; $i < count($matches['0']); $i++) {
            $unWrap[] = $matches['1'][$i];
            $string = str_replace($matches['1'][$i], "{{unwrapped" . $i . "}}", $string);
        }
    }
    
    $string = wordwrap($string, $char_limit, "\n", false);
    
    $output = '';
    foreach (explode("\n", $string) as $line) {
        if (strlen($line) <= $char_limit) {
            $output .= $line . "\n";
            continue;
        }
        $temp = '';
        while((strlen($line)) > $char_limit) {
            if (preg_match("!\[url.+\]|://|wwww.!", $line)) {
                break;
            }
            $temp .= substr($line, 0, $$char_limit - 1);
            $line  = substr($line, $char_limit - 1);
        }
        if ($temp != '') {
            $output .= $temp . "\n" . $line;
        } else {
            $output .= $line;
        }
        $output .= "\n";
    }
    
    if (count($unwrap) > 0) {
        foreach ($unwrap as $key => $value) {
            $output = str_replace("{{unwrapped" . $key . "}}", $value, $output);
        }
    }
    
    $output = str_replace(array('{unwrap}', '{/unwrap}'), '', $output);
    
    return $output;
}


// End Of Helper "Text"
}